﻿using FPSO.Models.Constant;
using FPSO.Models.Domain;
using FPSO.Models.ViewModel.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace FPSO.Services.Impl
{
    /// <summary>
    /// 模拟倒仓和外输的任务实现
    /// </summary>
    public class ImitateOutAndSwapService : IDataBindingService
    {
        private UCOutAndSwapViewModel viewModel;
        private List<TankOilViewModel> oilTankViewList;
        private List<ValveViewModel> valveViewList;
        private ITankTaskService taskService;

        public ImitateOutAndSwapService(UCOutAndSwapViewModel viewModel, ITankTaskService taskService)
        {
            this.viewModel = viewModel;
            this.taskService = taskService;
            this.oilTankViewList = new List<TankOilViewModel>();
            this.valveViewList = new List<ValveViewModel>();

            PropertyInfo[] propertys = typeof(UCOutAndSwapViewModel).GetProperties();
            foreach(PropertyInfo p in propertys)
            {
                object propVal = p.GetValue(viewModel);

                if (propVal is TankOilViewModel o)
                {
                    oilTankViewList.Add(o);
                }
                else if (propVal is ValveViewModel v)
                {
                    valveViewList.Add(v);
                }
            }
        }

        public void ReflushData(DateTime currentTime)
        {
            HashSet<string> openValveSet = new HashSet<string>();
            List<TankTask> taskList = taskService.GetWaitAndExecingTaskList(TaskQueueConstant.UNLOAD_TASK_1_ID);
            foreach(TankTask task in taskList)
            {
                if (currentTime < task.PlanStartTime || currentTime > task.PlanEndTime)
                    continue;

                if (task.TaskType == TaskTypeConstant.SWAP_ID)
                {
                    ImitateSwapTask(task, currentTime, openValveSet);
                }
                else
                {
                    ImitateOutTask(task, currentTime, openValveSet);
                }
            }

            foreach(ValveViewModel valve in valveViewList)
            {
				double a = 0;
				//valve.Active = openValveSet.Contains(valve.ValveId);
            }

            //这里要通过舱室和相关设备ID绑定，不能这样写死（待修改）
            //viewModel.HULL_P_9101I.Running = viewModel.HULL_BFV_91199.Active;
            //viewModel.HULL_P_9101G.Running = viewModel.HULL_BFV_91201.Active;
            //viewModel.HULL_P_9101E.Running = viewModel.HULL_BFV_91206.Active;
            //viewModel.HULL_P_9101C.Running = viewModel.HULL_BFV_91202.Active;
            //viewModel.HULL_P_9101A.Running = viewModel.HULL_BFV_91205.Active;

            //viewModel.HULL_P_9101J.Running = viewModel.HULL_BFV_91198.Active;
            //viewModel.HULL_P_9101H.Running = viewModel.HULL_BFV_91200.Active;
            //viewModel.HULL_P_9101F.Running = viewModel.HULL_BFV_91207.Active;
            //viewModel.HULL_P_9101D.Running = viewModel.HULL_BFV_91203.Active;
            //viewModel.HULL_P_9101B.Running = viewModel.HULL_BFV_91204.Active;
        }

        public void ReflushData(ManualCalcResult calcResult)
        {

        }

        private void ImitateOutTask(TankTask task, DateTime currentTime, HashSet<string> valveSet)
        {
            TankOilViewModel tankModel = oilTankViewList.Where(t => t.TankId == task.TankId).FirstOrDefault();
            if (tankModel != null)
            {
                double taskHours = (task.PlanEndTime - task.PlanStartTime).TotalHours;
                double curHours = (currentTime - task.PlanStartTime).TotalHours;
                tankModel.Rate = task.PipeSpeed;
                tankModel.Volume = tankModel.TotalVolume * task.TargetVolm * 0.01 * curHours / taskHours;
            }
        }

        private void ImitateSwapTask(TankTask task, DateTime currentTime, HashSet<string> valveSet)
        {
            TankOilViewModel tankModel = oilTankViewList.Where(t => t.TankId == task.TankId).FirstOrDefault();
            TankOilViewModel targetModel = oilTankViewList.Where(t => t.TankId == task.SwapTargetTank1).FirstOrDefault();
            if (tankModel != null && targetModel != null)
            {
                double taskHours = (task.PlanEndTime - task.PlanStartTime).TotalHours;
                double curHours = (currentTime - task.PlanStartTime).TotalHours;
                tankModel.Rate = task.PipeSpeed;
                targetModel.Rate = task.PipeSpeed;
                double newVolume = tankModel.TotalVolume * task.TargetVolm * 0.01 * curHours / taskHours;
                targetModel.Volume += (tankModel.Volume - newVolume);
                tankModel.Volume = newVolume;
            }
        }
    }
}
